package it.unibo.refolding.pico;

import it.unibo.refolding.common.LoggingInvocationHandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;

/**
 * Adds some sleeping time before some operations that seem to require a longer
 * break on Nanoscope V than on III, even with a faster computer.
 */
public class DelayedNanoDriverInvocationHandler implements InvocationHandler {

  private final NanoDriver delegate;
  private final long delayMillis;

  private final LoggingInvocationHandler delegateInvocationHandler;

  public DelayedNanoDriverInvocationHandler(NanoDriver delegate, long delayMillis) {
    this.delegate = delegate;
    delegateInvocationHandler = new LoggingInvocationHandler(Level.FINE, delegate);
    this.delayMillis = delayMillis;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    delegate.sleep(delayMillis / 1e3);
    return delegateInvocationHandler.invoke(proxy, method, args);
  }

  public static NanoDriver wrapIfNecessary(NanoDriver delegate, long delayMillis) {
    return delayMillis == 0 ? delegate : (NanoDriver) Proxy.newProxyInstance(
      DelayedNanoDriverInvocationHandler.class.getClassLoader(), new Class<?>[] {NanoDriver.class},
      new DelayedNanoDriverInvocationHandler(delegate, delayMillis));
  }
}
